package system

import (
	"fmt"
	"github.com/shirou/gopsutil/v3/disk"
	"os"
	"os/exec"
	"os/user"
	"runtime"
	"strings"
)

// 获取cpu几核
func GetCpuCore() int {
	return runtime.NumCPU()
}

// 获取cpu架构
func GetCpuArch() string {
	return runtime.GOARCH
}

// 获取操作系统
func GetOs() string {
	return runtime.GOOS
}

// 获取可用内存(MB)
func GetMem() uint64 {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	return m.Sys / 1024 / 1024
}

// 获取当前运行的goroutine数量
func GetGoroutine() int {
	return runtime.NumGoroutine()
}

// 获取本地指定磁盘的使用情况
// path: 磁盘路径 , 如: "c:"(windows), "/"(linux)
// 返回值: 总容量, 已使用容量, 可用容量, 使用率, 文件系统类型(可能为空)  (单位: MB)
func GetDiskInfo(path string) (uint64, uint64, uint64, float64, string) {
	// 使用 gopsutil 获取磁盘使用情况
	usage, err := disk.Usage(path)
	if err != nil {
		panic(err)
	}
	return usage.Total / 1024 / 1024, usage.Used / 1024 / 1024, usage.Free / 1024 / 1024, usage.UsedPercent, usage.Fstype
}

// 获取有效的磁盘, 返回磁盘挂载点
func GetValidDisk() []string {
	partitions, err := disk.Partitions(true)
	if err != nil {
		panic(err)
	}
	var result []string
	for _, partition := range partitions {
		result = append(result, partition.Mountpoint)
	}
	return result
}

// 获取PATH环境变量
func GetEnvPath() []string {
	getenv := os.Getenv("PATH")
	//根据不同的操作系统进行分割
	var envPath []string
	if runtime.GOOS == "windows" {
		split := strings.Split(getenv, ";")
		for _, v := range split {
			envPath = append(envPath, v)
		}
		return envPath
	} else {
		split := strings.Split(getenv, ":")
		for _, v := range split {
			envPath = append(envPath, v)
		}
		return envPath
	}
}

// 修改环境变量
func UpdateEnv(key string, value string) {
	err := os.Setenv(key, value)
	if err != nil {
		panic(err)
	}
}

func getEnvAll() []string {
	return os.Environ()
}

// 清屏
func ClearScreen() {
	var cmd *exec.Cmd
	if runtime.GOOS == "windows" {
		cmd = exec.Command("cmd", "/c", "cls")
	} else {
		cmd = exec.Command("clear")
	}
	cmd.Stdout = os.Stdout
	err := cmd.Run()
	if err != nil {
		panic(err)
	}
}

// 判断系统环境变量是否存在
func IsEnvExist(key string) bool {
	_, ok := os.LookupEnv(key)
	return ok
}

// 获取系统环境变量
func GetEnv(key string) string {
	return os.Getenv(key)
}

// 添加系统环境变量，如果存在则覆盖
func SetEnv(key string, value string) {
	exist := IsEnvExist(key)
	if exist {
		UnsetEnv(key)
	}
	os.Setenv(key, value)
}

// 修改PATH环境变量
func SetEnvPath(oldPath string, newPath string) {
	envPath := GetEnvPath()
	for i, v := range envPath {
		if v == oldPath {
			envPath[i] = newPath
			break
		}
	}
	//根据不同的操作系统进行拼接
	if runtime.GOOS == "windows" {
		path := strings.Join(envPath, ";")
		err := os.Setenv("PATH", path)
		if err != nil {
			panic(err)
		}
	} else {
		path := strings.Join(envPath, ":")
		err := os.Setenv("PATH", path)
		if err != nil {
			panic(err)
		}
	}
}

// 添加path环境变量
func SetPathEnv(value string) {
	path := GetEnv("PATH")
	//判断path是否已经存在
	if strings.Contains(path, path) {
		return
	}
	//判断是：还是;
	if strings.Contains(path, ":") {
		//判断结尾是否有分号，没有则添加
		if path[len(path)-1] != ':' {
			path += ":"
		}
	}
	if strings.Contains(path, ";") {
		//判断结尾是否有分号，没有则添加
		if path[len(path)-1] != ';' {
			path += ";"
		}
	}

	SetEnv("PATH", path+value)
}

// 删除path环境变量
func UnsetPathEnv(value string) {
	path := GetEnv("PATH")
	//判断path是否已经存在
	if !strings.Contains(path, value) {
		return
	}
	//判断是：还是;
	if strings.Contains(path, ":") {
		path = strings.Replace(path, ":"+value, "", -1)
	}
	if strings.Contains(path, ";") {
		path = strings.Replace(path, ";"+value, "", -1)
	}
	SetEnv("PATH", path)
}

// 删除系统环境变量
func UnsetEnv(key string) {
	err := os.Unsetenv(key)
	if err != nil {
		return
	}
}

// 将当前程序所在目录添加到path环境变量
func SetCurrentPathToPathEnv() {
	path := GetCurrentPath()
	//判断path是否已经存在
	if strings.Contains(path, GetEnv("PATH")) {
		return
	}
	SetPathEnv(path)
}

// 获取当前程序所在目录
func GetCurrentPath() string {
	path, err := os.Getwd()
	if err != nil {
		fmt.Println("获取当前程序所在目录失败:", err)
		return ""
	}
	return path
}

// 退出程序，这种退出方式是通过系统来杀死进程的，而os.exit是通过go语言来退出的
func Exit() {
	process, err := os.FindProcess(os.Getpid())
	if err != nil {
		fmt.Println("获取进程信息失败:", err)
		return
	}
	err1 := process.Kill()
	if err1 != nil {
		fmt.Println("杀死进程失败:", err)
		return
	}
}

// 获取当前系统的用户名
func GetUserName() string {
	current, err := user.Current()
	if err != nil {
		fmt.Println("获取用户名失败:", err)
		return ""
	}
	username := current.Username
	//截取用户名
	if strings.Contains(username, "\\") {
		split := strings.Split(username, "\\")
		username = split[1]
	}
	return username
}
